package com.raptor.redis.spring;

import com.raptor.redis.config.RedisConfigBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

/**
 * @program: raptor-boot
 */
public class RedisRegisterBean {
    private final RedisConfigBean redisRegisterBean;

    private final ConfigurableApplicationContext configurableApplicationContext;

    public RedisRegisterBean(RedisConfigBean redisRegisterBean, ConfigurableApplicationContext configurableApplicationContext) {
        this.redisRegisterBean = redisRegisterBean;
        this.configurableApplicationContext = configurableApplicationContext;
    }

    public void RegisterRedisBean() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(this.redisRegisterBean.getHost());
        configuration.setPort(this.redisRegisterBean.getPort());
        String password = this.redisRegisterBean.getPassword();
        if (!StringUtils.isEmpty(password)) {
            configuration.setPassword(password);
        }

        JedisClientConfiguration.DefaultJedisClientConfigurationBuilder defaultJedisClientConfigurationBuilder = (JedisClientConfiguration.DefaultJedisClientConfigurationBuilder) JedisClientConfiguration.builder();
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(this.redisRegisterBean.getMaxidle());
        config.setMinIdle(this.redisRegisterBean.getMinidle());
        config.setMaxWaitMillis(this.redisRegisterBean.getMaxwait());
        config.setMaxTotal(this.redisRegisterBean.getMaxactive());

        int timeout = this.redisRegisterBean.getTimeout();
        if (timeout > 0) {
            defaultJedisClientConfigurationBuilder.connectTimeout(Duration.ofMillis(timeout));
        }
        defaultJedisClientConfigurationBuilder.usePooling();
        defaultJedisClientConfigurationBuilder.poolConfig(config);

        JedisClientConfiguration jedisClientConfiguration = defaultJedisClientConfigurationBuilder.build();

        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration, jedisClientConfiguration);
        jedisConnectionFactory.afterPropertiesSet();

        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisTemplate.class);
        // beanDefinitionBuilder.addConstructorArgValue(jedisConnectionFactory);
        beanDefinitionBuilder.addPropertyValue("connectionFactory", jedisConnectionFactory);
        String instance = this.redisRegisterBean.getInstanceName();

        if (instance.endsWith("write")) {
            beanDefinitionBuilder.setPrimary(true);
        }

        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) this.configurableApplicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(instance, beanDefinition);
    }

}
